/* 
 * Copyright (C) 2012 UTSChedule
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package utsc.apps.utschedule.ui.activities;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;

import utsc.apps.utschedule.R;
import utsc.apps.utschedule.UTSCheduleApp;
import utsc.apps.utschedule.classes.Course;
import utsc.apps.utschedule.classes.Exam;
import utsc.apps.utschedule.classes.Timetable;
import utsc.apps.utschedule.ui.interfaces.OnSyncListener;
import utsc.apps.utschedule.util.TimetableHelper;
import utsc.apps.utschedule.util.database.DatabaseManager;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;

import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;

/**
 * This AsyncTask is used to perform a synchronisation of the course exams
 * from Intranet. It makes a call to our dummy webservice to retrieve the course
 * exam data.
 * 
 */
public class SyncExamTask extends AsyncTask<Void, Void, ArrayList<Exam>> {
	
	private Context _context;
	public SyncExamTask(Context context){
		this._context=context;
	}
	
	private String _term;
	private ProgressDialog _progressDialog;
	/**
	 * The dummy webservice url we created.
	 */
	private static final String URL="http://utschedule.comoj.com/exam_schedule.php?courses=%s&term=%s";
	public SyncExamTask(Context context, String term) {
		_context=context;
		_term=term;
	}
	
	@Override
	protected void onPreExecute() {
		super.onPreExecute();
		_progressDialog=new ProgressDialog(_context);
		_progressDialog.setMessage(_context.getResources().getText(R.string.loading));
		_progressDialog.show();
	}
	
	@Override
	protected ArrayList<Exam> doInBackground(Void...voids) {
		InputStream is = null;
	    try {
	    	UTSCheduleApp app =(UTSCheduleApp)(_context.getApplicationContext());
	    	Timetable timetable=app.get_currentActiveTimetable();
	    	
	    	if (timetable!=null) {
	    		DatabaseManager dbManager=DatabaseManager.getInstance(_context);
	    		ArrayList<Course> courses=new ArrayList<Course>(dbManager.getCoursesWithoutTutorials(timetable.get_timetableID()));
		    	if (courses!=null && !courses.isEmpty()) {
					StringBuilder sBuilder=new StringBuilder();
					HashMap<String, Course> courseMap=new HashMap<String, Course>(courses.size());
					for (Course course : courses) {
						sBuilder.append(course.get_courseCode()).append(",");
						courseMap.put(course.get_courseCode(), course);
					}
					String courseCodes=sBuilder.substring(0, sBuilder.length()-1);
					URL url = new URL(String.format(URL,courseCodes,_term));
			        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			        conn.setReadTimeout(10000 /* milliseconds */);
			        conn.setConnectTimeout(15000 /* milliseconds */);
			        conn.setDoInput(true);
			        // Starts the query
			        conn.connect();
			        int response = conn.getResponseCode();
			        //check the status of the response
			        if (response==HttpURLConnection.HTTP_OK) {
			        	is = new BufferedInputStream(conn.getInputStream());
			        	is.mark(1<<24);
			        	if (is.read()==-1) {
			        		if (is!=null) {
			        			is.close();
							}
							return null;
						}else {
							//parse the returned json results into a list of exams
							is.reset();
							JsonReader reader=new JsonReader(new InputStreamReader(is,"UTF-8"));
				        	ArrayList<Exam> results=new ArrayList<Exam>();
				        	reader.beginArray();
				        		while (reader.hasNext()) {
									reader.beginObject();
									Exam e=new Exam();
									while (reader.hasNext()) {
										String name=reader.nextName();
										if (name.equals("course")&&reader.peek()!=JsonToken.NULL) {
											e.set_course(courseMap.get(reader.nextString()));
										}else if (name.equals("examdate")&&reader.peek()!=JsonToken.NULL) {
											e.set_dateString(reader.nextString());
										}else if (name.equals("starttime")&&reader.peek()!=JsonToken.NULL) {
											e.set_startTimeString(reader.nextString());
										}else if (name.equals("endtime")&&reader.peek()!=JsonToken.NULL) {
											e.set_endTimeString(reader.nextString());
										}else if (name.equals("location")&&reader.peek()!=JsonToken.NULL) {
											e.set_location(reader.nextString());
										}else if (name.equals("isfinal")&&reader.peek()!=JsonToken.NULL) {
											e.set_type(reader.nextBoolean()?Exam.TYPE_FINAL:Exam.TYPE_MIDTERM);
										}else {
											reader.skipValue();
										}
									}
									reader.endObject();
									e.set_timetable(timetable);
									e.set_startTime(TimetableHelper.convertFromDateTimeStringToMillis(e.get_dateString()+" "+e.get_startTimeString(), TimetableHelper.TYPE_DATETIME_EXAM).getTime());
									e.set_endTime(TimetableHelper.convertFromDateTimeStringToMillis(e.get_dateString()+" "+e.get_endTimeString(), TimetableHelper.TYPE_DATETIME_EXAM).getTime());
									results.add(e);
								}
				        	reader.endArray();
				        	reader.close();
				        	return results;
						}
					}
				}
			}
	    	
	        return null;
	        
	    // Makes sure that the InputStream is closed after the app is
	    // finished using it.
	    } catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
		return null;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	protected void onPostExecute(ArrayList<Exam> result) {
		_progressDialog.dismiss();
		((OnSyncListener<Exam>)_context).onSyncCompleted(result);
	}


}
